package com.gt.wxpay.cashier.payChannel.application.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gt.wxpay.cashier.common.RuleCommonUilt;
import com.gt.wxpay.cashier.domain.model.PayTypeEnum;
import com.gt.wxpay.cashier.payChannel.application.PayChannelService;
import com.gt.wxpay.cashier.payChannel.application.WxConfigService;
import com.gt.wxpay.cashier.payChannel.domain.model.PayChannel;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * packageName com.gt.wxpay.cashier.payment
 *
 * @author GuoTong
 * @version JDK 8
 * @className WxConfigService
 * @date 2024/3/16
 * @description 获取微信支付的配置
 */
@Service
public class WxConfigServiceImpl implements WxConfigService {
    private Logger logger = LoggerFactory.getLogger(WxConfigServiceImpl.class);
    @Autowired
    private PayChannelService payChannelService;

    @Autowired
    private Environment environment;

    private Config config = null;
    private NotificationConfig notificationConfig = null;

    private PayChannel payChannel = null;

    @Value("${test.windows.certPath:D:\\BaiduNetdiskDownload\\微信支付秘密\\apiclient_key.pem}")
    private String certPathTestByWindows;

    @Override
    public Config getWxConfig(Long channelId) {
        if (config != null) {
            return config;
        }
        payChannel = payChannelService.getById(channelId);
        if (payChannel == null) {
            throw new RuntimeException("支付通道不存在");
        }
        String merchantId = payChannel.getMerchantId();
        String certPath = payChannel.getCertPath();
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            certPath = certPathTestByWindows;
        }
        String merchantSerialNumber = payChannel.getMerchantSerialNumber();
        String apiV3key = payChannel.getPrivateKey();
        // 获取微信支付的配置
        config = getConfig(merchantId, certPath, merchantSerialNumber, apiV3key);
        return config;
    }

    @Override
    public Config getWxConfig(PayTypeEnum payTypeEnumType) {
        if (config != null) {
            return config;
        }
        PayChannel channel = new PayChannel();
        channel.setPayChannel(payTypeEnumType.getCode());
        channel.setStateId(1);
        QueryWrapper<PayChannel> queryWrapper = new QueryWrapper<>(channel);
        List<PayChannel> payChannels = payChannelService.list(queryWrapper);
        if (CollectionUtils.isEmpty(payChannels)) {
            logger.error("未找到支付通道");
            return null;
        }
        PayChannel payChannelVarT = payChannels.get(0);
        String merchantId = payChannelVarT.getMerchantId();
        String certPath = payChannelVarT.getCertPath();
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            certPath = certPathTestByWindows;
        }
        String merchantSerialNumber = payChannelVarT.getMerchantSerialNumber();
        String apiV3key = payChannelVarT.getPrivateKey();
        // 获取微信支付的配置
        config = getConfig(merchantId, certPath, merchantSerialNumber, apiV3key);
        // 渠道赋值
        payChannel = payChannelVarT;
        return config;
    }

    @Override
    public NotificationConfig getCallBackConfig(Long channelId) {
        if (notificationConfig != null) {
            return notificationConfig;
        }
        if (payChannel == null) {
            payChannel = payChannelService.getById(channelId);
        }
        String merchantId = payChannel.getMerchantId();
        String certPath = payChannel.getCertPath();
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            certPath = certPathTestByWindows;
        }
        String merchantSerialNumber = payChannel.getMerchantSerialNumber();
        String apiV3key = payChannel.getPrivateKey();
        notificationConfig = getConfig(merchantId, certPath, merchantSerialNumber, apiV3key);
        return notificationConfig;
    }

    @Override
    public NotificationConfig getCallBackConfig(PayTypeEnum payTypeEnumType) {
        if (notificationConfig != null) {
            return notificationConfig;
        }
        if (payChannel == null) {
            PayChannel channel = new PayChannel();
            channel.setPayChannel(payTypeEnumType.getCode());
            channel.setStateId(1);
            QueryWrapper<PayChannel> queryWrapper = new QueryWrapper<>(channel);
            List<PayChannel> payChannels = payChannelService.list(queryWrapper);
            if (CollectionUtils.isEmpty(payChannels)) {
                logger.error("未找到支付通道");
                return null;
            }
            payChannel = payChannels.get(0);
        }
        String merchantId = payChannel.getMerchantId();
        String certPath = payChannel.getCertPath();
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            certPath = certPathTestByWindows;
        }
        String merchantSerialNumber = payChannel.getMerchantSerialNumber();
        String apiV3key = payChannel.getPrivateKey();
        notificationConfig = getConfig(merchantId, certPath, merchantSerialNumber, apiV3key);
        return notificationConfig;
    }

    private static RSAAutoCertificateConfig getConfig(String merchantId, String certPath, String merchantSerialNumber, String apiV3key) {
        return new RSAAutoCertificateConfig.Builder()
                .merchantId(merchantId)
                .privateKeyFromPath(certPath)
                .merchantSerialNumber(merchantSerialNumber)
                .apiV3Key(apiV3key)
                .build();
    }

    @Override
    public PayChannel getPayChannel(Long channelId) {
        if (channelId != null) {
            return payChannelService.getById(channelId);
        }
        if (payChannel == null) {
            PayChannel channel = new PayChannel();
            channel.setPayChannel(PayTypeEnum.WECHAT.getCode());
            channel.setStateId(1);
            QueryWrapper<PayChannel> queryWrapper = new QueryWrapper<>(channel);
            List<PayChannel> payChannels = payChannelService.list(queryWrapper);
            if (CollectionUtils.isEmpty(payChannels)) {
                logger.error("未找到支付通道");
                return null;
            }
            payChannel = payChannels.get(0);
        }
        return payChannel;
    }

    @Override
    public String getWxCallBackUrl(boolean isRefund) {
        if (!isRefund) {
            String callBackUrl = environment.getProperty(RuleCommonUilt.WX_CALL_BACK_URL_SYSTEM);
            if (StringUtils.isEmpty(callBackUrl)) {
                return "https://cashier.chinamuseum.cn/wxpay/notify/pay";
            } else {
                callBackUrl = callBackUrl + "/wxpay/notify/pay";
            }
            return callBackUrl;
        } else {
            String callBackUrl = environment.getProperty(RuleCommonUilt.WX_CALL_BACK_URL_SYSTEM);
            if (StringUtils.isEmpty(callBackUrl)) {
                return "https://cashier.chinamuseum.cn/wxpay/notify/refund";
            } else {
                callBackUrl = callBackUrl + "/wxpay/notify/refund";
            }
            return callBackUrl;
        }
    }

}
